package Lexicon;

import gui.ArMT;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;


import javax.swing.UnsupportedLookAndFeelException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;



import java.util.Enumeration;
import java.util.Vector;



public class Lexicon implements WordType{
	
	DocumentBuilderFactory docBuilderFactory ;
	 DocumentBuilder docBuilder ;
	public static BinaryTree wordTree = new BinaryTree();;
	public static BinaryTree searchTree  = new BinaryTree();
	public static BinaryTree currentTree = new BinaryTree();; 
	Word nonrecognizedWord ; 
	Document doc ;
	MyNode node ;
	Stemmer stem ;
	String pre;
	String in;
	String suf;
	boolean inflected ;
	public static Lexicon lex ;
	public Lexicon() throws SAXException, IOException, ParserConfigurationException
	{	 	
		 docBuilderFactory = DocumentBuilderFactory.newInstance();
         docBuilder = docBuilderFactory.newDocumentBuilder();   
         
//         doc = docBuilder.parse(new File("resources\\Dic.xml"));       
//         doc.getDocumentElement().normalize ();  
//         load_4_Data(doc.getElementsByTagName("entry"),WordType.ACCUSATIVE);
         /*-------load two entries dictionaries-----------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"accusative.xml"));       
         doc.getDocumentElement().normalize ();  
         load_2_Data(doc.getElementsByTagName("entry"),WordType.ACCUSATIVE);
         /*------------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"prepos.xml"));
         doc.getDocumentElement().normalize ();  
         load_2_Data(doc.getElementsByTagName("entry"),WordType.PREPOSITION);
         /*------------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"inna_verbs.xml"));
         doc.getDocumentElement().normalize ();  
         load_2_Data(doc.getElementsByTagName("entry"),WordType.INNA_VERB);
         
         
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"connect.xml"));
         doc.getDocumentElement().normalize ();  
         load_2_Data(doc.getElementsByTagName("entry"),WordType.CONNECTOR);
         /*------load 4 entries dictionaries---------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"defined_nouns.xml"));
         //    normalize text representation           
         doc.getDocumentElement().normalize ();
         load_4_Data(doc.getElementsByTagName("entry"),WordType.DEFINED_NOUN);
         /*---------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"indeter_nouns.xml"));         
         doc.getDocumentElement().normalize ();   
         load_4_Data(doc.getElementsByTagName("entry"),WordType.INDETERMINATE_NOUN);
         /*---------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"demonstrative.xml"));         
         doc.getDocumentElement().normalize ();   
         load_4_Data(doc.getElementsByTagName("entry"),WordType.DEMONSTRATIVE);
         /*---------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"relative_pron.xml"));        
         doc.getDocumentElement().normalize ();   
         load_4_Data(doc.getElementsByTagName("entry"),WordType.RELATIVE_PRONOUN);
         /*---------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"separated_pron.xml"));       
         doc.getDocumentElement().normalize ();   
         load_4_Data(doc.getElementsByTagName("entry"),WordType.SEPARATED_PRONOUN);
         /*---------------*ArMT.FILE_SEPARATOR         doc = docBuilder.parse(new File("resources"+sep+"conjun.xml"));       
         doc.getDocumentElement().normalize ();   
         load_4_Data(doc.getElementsByTagName("entry"),WordType.CONJUNCTIVE);
         
         
         /*--------------------*************----------------------*/
        
         /*------------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"kana_verbs.xml"));
         doc.getDocumentElement().normalize ();  
         load_2_Data(doc.getElementsByTagName("entry"),WordType.KANA_VERB);
//         /*------------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"normal_verbs.xml"));
         doc.getDocumentElement().normalize ();  
         load_4_Data(doc.getElementsByTagName("entry") , WordType.NORMAL_VERB);
         
         /*-------------------------------------*/
         doc = docBuilder.parse(new File("resources"+ArMT.FILE_SEPARATOR+"Dic_part1.xml"));
         doc.getDocumentElement().normalize ();  
         load_3_Data(doc.getElementsByTagName("entry"));
         
         //JOptionPane.showMessageDialog(null,wordTree.find("��").englishWord);
         //JOptionPane.showMessageDialog(null,wordTree.find("�����").englishWord);
         //JOptionPane.showMessageDialog(null,wordTree.find("���").englishWord);
//       JOptionPane.showMessageDialog(null,""+wordTree.find("��").type);
//        JOptionPane.showMessageDialog(null,""+(wordTree.find("���").type));
//         JOptionPane.showMessageDialog(null,wordTree.find("��-����").englishWord);
         /*------------------*/
         
	}
	public void load_4_Data(NodeList listOfEntries ,int type)
	{
		//String st = new String("ghh");

		int totalEntries = listOfEntries.getLength();
        Node entryNode ;
        Element firstEntryElement ;
        for(int s=0; s<totalEntries; s++){
       	 entryNode = listOfEntries.item(s);
            if(entryNode.getNodeType() == Node.ELEMENT_NODE){
           	firstEntryElement = (Element)entryNode;
                //               -------       
           	 NodeList arNameList = firstEntryElement.getElementsByTagName("ar");
                Element arNameElement = (Element)arNameList.item(0);
                NodeList textFNList = arNameElement.getChildNodes();     
                //               -------                    
                NodeList enNameList = firstEntryElement.getElementsByTagName("en");
                Element enNameElement = (Element)enNameList.item(0);
                NodeList textLNList = enNameElement.getChildNodes();
               //             -------   
                NodeList numList = firstEntryElement.getElementsByTagName("num");
                Element numElement = (Element)numList.item(0);
                NodeList textnumList = numElement.getChildNodes();
                //               -------   
                NodeList genList = firstEntryElement.getElementsByTagName("gen");
                Element genElement = (Element)genList.item(0);
                NodeList textgenList = genElement.getChildNodes();
                
                /*--------****************-------------*/
               
                wordTree.insert(
               		 ((Node)textFNList.item(0)).getNodeValue().trim().toString()
               		 ,((Node)textLNList.item(0)).getNodeValue().trim().toString()
               		 ,type
               		 ,Integer.parseInt(((Node)textnumList.item(0)).getNodeValue().trim().toString())
               	     ,Integer.parseInt(((Node)textgenList.item(0)).getNodeValue().trim().toString())
               	     );
        }
        }
	}
    /*********************This is for External dictionary**********************/
	public void load_3_Data(NodeList listOfEntries)
	{
		int totalEntries = listOfEntries.getLength();
        Node entryNode ;
        Element firstEntryElement ;
        for(int s=0; s<totalEntries; s++){
       	 entryNode = listOfEntries.item(s);
            if(entryNode.getNodeType() == Node.ELEMENT_NODE){
           	firstEntryElement = (Element)entryNode;
                //               -------       
           	 NodeList arNameList = firstEntryElement.getElementsByTagName("word");
                Element arNameElement = (Element)arNameList.item(0);
                NodeList textFNList = arNameElement.getChildNodes();     
                //               -------                    
                NodeList enNameList = firstEntryElement.getElementsByTagName("eng_word");
                Element enNameElement = (Element)enNameList.item(0);
                NodeList textLNList = enNameElement.getChildNodes();
               //             -------   
                NodeList numList = firstEntryElement.getElementsByTagName("pos");
                Element numElement = (Element)numList.item(0);
                NodeList textnumList = numElement.getChildNodes();              
          
            //*********************************
                searchTree.insert(
               		 ((Node)textFNList.item(0)).getNodeValue().trim().toString()
               		 ,((Node)textLNList.item(0)).getNodeValue().trim().toString()
               		 ,((Node)textnumList.item(0)).getNodeValue().trim().toString()         
               	     );
        }
        }
	}
	
	private void load_2_Data(NodeList listOfEntries ,int type)
	{
		int totalEntries = listOfEntries.getLength();
        Node entryNode ;
        Element firstEntryElement ;
        for(int s=0; s<totalEntries; s++){
       	 entryNode = listOfEntries.item(s);
            if(entryNode.getNodeType() == Node.ELEMENT_NODE){
           	firstEntryElement = (Element)entryNode;
                //               -------       
           	 NodeList arNameList = firstEntryElement.getElementsByTagName("ar");
                Element arNameElement = (Element)arNameList.item(0);
                NodeList textFNList = arNameElement.getChildNodes();     
                //               -------                    
                NodeList enNameList = firstEntryElement.getElementsByTagName("en");
                Element enNameElement = (Element)enNameList.item(0);
                NodeList textLNList = enNameElement.getChildNodes();    
                
                /*---------------------*/
               
                wordTree.insert(
               		 ((Node)textFNList.item(0)).getNodeValue().trim().toString()
               		 ,((Node)textLNList.item(0)).getNodeValue().trim().toString()  
               		 ,type
               	     );
        }
        }
	}
	/**
	 * @throws IOException */
	@SuppressWarnings("unchecked")
	public void store_data(String fileName , String encoding) throws IOException
	{
		 OutputStream  fout= new FileOutputStream(fileName);
		 OutputStream bout= new BufferedOutputStream(fout);
	        OutputStreamWriter out 
	         = new OutputStreamWriter(bout,"UTF8");
//		 OutputStreamWriter o = new OutputStreamWriter(fout,encoding);
//		 BufferedWriter bw = new BufferedWriter(o);
		 Vector v = new Vector();
         v = wordTree.traverseInOrder(wordTree.getRoot(),v);
		 Enumeration enumer = v.elements(); 
		 MyNode []nodes =  new MyNode[v.size()]   ;
		// StringBuffer s =new StringBuffer
		 out.write("<dictionary>"+"\r\n")  ;
		 for(int i = 0 ; i< nodes.length ; i++)
		 {
			 nodes[i] = (MyNode)enumer.nextElement();
		 out.write("\t"+"<entry>"+"\r\n");
			 out.write("\t\t"+"<ar>");out.write(nodes[i].arabicWord);out.write("</ar>"+"\r\n");
			 out.write("\t\t"+"<en>");out.write(nodes[i].englishWord);out.write("</en>"+"\r\n");
			 out.write("\t\t"+"<type>");out.write(""+nodes[i].type);out.write("</type>"+"\r\n");
			 out.write("\t\t"+"<num>");out.write(""+nodes[i].number);out.write("</num>"+"\r\n");
			 out.write("\t\t"+"<gen>");out.write(""+nodes[i].gender);out.write("</gen>"+"\r\n");
		 out.write("\t"+"</entry>"+"\r\n");
		 }
		 out.write("</dictionary>");
		 String path = new String("\""+fileName+"\"");
			Runtime runtime =Runtime.getRuntime();
			Process p = null;
			try {
				p = runtime.exec ("rundll32 SHELL32.DLL,ShellExec_RunDLL " + path);
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			try {
				p.waitFor();
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		// JOptionPane.showMessageDialog(null, );
//		 bw.write(s.toString());
		 out.flush();
		 out.close();
	}
	/*
	 * Unit testing : Test Lexicon class*/
//	 throws IOException, ParserConfigurationException
//	{ 
////		
//	try {
//			lex =  new Lexicon();
////			// JOptionPane.showMessageDialog(null,wordTree.getRoot().arabicWord); 
//////			 Vector v = new Vector();
//////             v = wordTree.traverseInOrder(wordTree.getRoot(),v);
//////			 Enumeration en = v.elements(); 
//////			 int i = 0;
//////			 MyNode []nodes =  new MyNode[v.size()]   ;
//////			 String [] s =new String[v.size()];
//////			 while(en.hasMoreElements())
//////			 { 
//////				 nodes[i] = (MyNode) en.nextElement();
//////				 s[i] = nodes[i].arabicWord +"\t"+ nodes[i].englishWord+"\t"+ nodes[i].number+"\t"+ nodes[i].gender;
//////				 i++ ;
//////			 }
//////			JFrame f =new JFrame("Test");
//////			JList l  = new JList(s);
//////			JScrollPane sp = new JScrollPane(l);
//////			f.getContentPane().add(sp);
//////			f.pack();
//////			f.setVisible(true);
////			//lex.store_data("E:\\java\\eclipse\\Training1\\ArMT\\h.XML" , "cp1256");
////				//lex.find("");			
//			}catch (SAXException e1) {
//		e1.printStackTrace();
//}
//}
	/*********************************************************/
	//pefore using this method ,be sure that the word is exist ,find(String) can do this 
	public boolean find(String word,int type) throws UnsupportedLookAndFeelException
	{  
	MyNode n = currentTree.find(word);
	if( n.type == type)//find directly0
	{
		return true ;
	} 	
	else return false ;		// faild
	}
	/*************************************************/
	public MyNode find(String word)
	{
		MyNode node = null ;
		node = wordTree.find(word);
		if(node == null)
		{
			stem =new Stemmer(word);
			//JOptionPane.showMessageDialog(null, "the word "+word);
			stem.stem();
			node = wordTree.find(stem.getIn());
			if(node != null)
			{
				inflected =true ;
			}		
		}			return node ;
	}
	/**
	 * @return  the inflected
	 * @uml.property  name="inflected"
	 */
	public boolean getInflected()
	{
		return inflected ;
	}
	/**
	 * @return  the pre
	 * @uml.property  name="pre"
	 */
	public String getPre()
	{
		return stem.getPre();
	}
	/**
	 * @return  the suf
	 * @uml.property  name="suf"
	 */
	public String getSuf()
	{
		return stem.getSuf();
	}
}
